#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = 'ben'
__mtime__ = '16-4-14'
"""


import sys
import tornado.web
import tornado.ioloop
from fdfs_client.client import Fdfs_client
from tornado.httpclient import AsyncHTTPClient, HTTPRequest
import logging
import os
import time
import json

from fdfs.fdfs_orm import CFdfsORM

logger = logging.getLogger('info')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('/home/log/fdfs_tornado.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)

asynClient = AsyncHTTPClient()


class FDFSJsonHandler(tornado.web.RequestHandler):
    def __init__(self, application, request, **kwargs):
        super(FDFSJsonHandler, self).__init__(application=application, request=request, **kwargs)

        self.fdfsOrm = CFdfsORM()
        self.logs = []

    def get(self):
        str_result = ''

        file_id = self.get_argument("file_id", None)
        if not file_id:
            raise Exception("no file_id paramter!")

        msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|start get|file_id=' + file_id
        self.logs.append(msg)

        try:
            result = self.fdfsOrm.get_data(file_id=file_id)
            ret = result

            if isinstance(result, dict):
                remote_file_id = result['remote_file_id']
                group_name = result['group_name']
                remote_file_id = remote_file_id.replace(group_name + '/', '')
                storage_ip = result['storage_ip']
                storage_port = result['storage_port']
                remote_file_id = 'http://' + storage_ip + ':' + str(storage_port) + '/' + remote_file_id

                ret['remote_file_id'] = remote_file_id

            msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|result|' + str(ret)
            self.logs.append(msg)
            str_result = str(ret)

        except Exception as e:
            msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|error|' + str(e)
            self.logs.append(msg)
            str_result = str(e)
        finally:
            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

            for i in self.logs:
                logger.log(logging.INFO, i)

            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

            self.set_header("Content-Type", "application/json;charset=utf-8")
            self.write(str_result)



class FDFSMainHandler(tornado.web.RequestHandler):

    def __init__(self, application, request, **kwargs):

        super(FDFSMainHandler, self).__init__(application=application, request=request, **kwargs)

        self.fdfsOrm = CFdfsORM()
        self.logs = []

    @tornado.web.asynchronous
    def get(self):
        file_id = self.get_argument("file_id",None)
        if not file_id:
            raise Exception("no file_id paramter!")

        msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|start get|file_id=' + file_id
        self.logs.append(msg)

        try:
            result = self.fdfsOrm.get_data(file_id=file_id)
            ret = result

            if isinstance(result, dict):

                remote_file_id = result['remote_file_id']
                group_name = result['group_name']
                remote_file_id = remote_file_id.replace(group_name + '/', '')
                storage_ip = result['storage_ip']
                storage_port = result['storage_port']
                remote_file_id = 'http://' + storage_ip + ':' + str(storage_port) + '/' + remote_file_id

                ret['remote_file_id'] = remote_file_id

                msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|remote_file_id|' + remote_file_id
                self.logs.append(msg)

                request = HTTPRequest(url=remote_file_id)
                asynClient.fetch(request=request, callback=self.callback_fetch)

        except Exception as e:
            msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|error|' + str(e)
            self.logs.append(msg)
            str_result = str(e)
            self.write(str_result)

    def callback_fetch(self, reponse):
        result = ''
        try:
            result = reponse.body
        except Exception as e:
            result = str(e)
        finally:
            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

            for i in self.logs:
                logger.log(logging.INFO, i)

            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

            self.set_status(reponse.code)
            self.write(result)
            self.finish()

    def post(self):
        result = []
        str_result = ''
        try:
            files = self.request.files["file"]

            for file in files:
                content = file['body']
                # print content
                client = Fdfs_client('/etc/fdfs/client.conf')
                file_id = file['filename']
                file_id = file_id.encode('utf8')
                msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|file_name|' + file_id
                self.logs.append(msg)

                names = os.path.splitext(file_id)
                if len(names) == 2:
                    ext = names[1]
                    ext = ext.lstrip('.')
                else:
                    ext = 'html'

                ret = client.upload_by_buffer(filebuffer=content)
                result.append(ret)
                msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|upload_result|' + str(ret)
                self.logs.append(msg)

                remote_file_id = ret['Remote file_id']
                status = ret['Status']
                group_name = ret['Group name']
                storage_ip = ret['Storage IP']
                file_size = ret['Uploaded size']
                local_file_name = ret['Local file name']
                create_time = time.time()

                new_file_dict = {}
                new_file_dict['file_id'] = file_id
                new_file_dict['remote_file_id'] = remote_file_id
                new_file_dict['status'] = status
                new_file_dict['group_name'] = group_name
                new_file_dict['storage_ip'] = storage_ip
                new_file_dict['file_size'] = file_size
                new_file_dict['local_file_name'] = local_file_name
                new_file_dict['create_time'] = create_time
                new_file_dict['ext'] = ext

                self.fdfsOrm.insert_data(file_upload_dict=new_file_dict)

            str_result = json.dumps(result)

        except Exception as e:
            msg = __file__ + '|' + str(sys._getframe().f_lineno) + '|' + '|error|' + str(e)
            self.logs.append(msg)
            str_result = str(e)
        finally:
            self.set_header("Content-Type", "application/json;charset=utf-8")
            self.write(str_result)

            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

            for i in self.logs:
                logger.log(logging.INFO, i)

            logger.log(logging.INFO, __file__ + '|' + str(
                sys._getframe().f_lineno) + '|---------------------------------------------------------------------------------')

settings = {
    'debug': False,  # 开发模式
    'gzip': True,  # 支持gzip压缩
    'autoescape': None,
    'xsrf_cookies': False,
    'cookie_secret': 'xxx'
}

application = tornado.web.Application([(r"/",FDFSMainHandler),(r"",FDFSMainHandler),(r"/json",FDFSJsonHandler)], **settings)

if __name__ == "__main__":
    # port = 8002
    port = int(sys.argv[1])
    application.listen(port=port)
    tornado.ioloop.IOLoop.instance().start()